package com.szf.base.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.szf.base.dao.Page;
import com.szf.base.dao.hb.HibernateDao;
import com.szf.base.dao.hb.HibernatePage;
import com.szf.base.dao.ibatis.IBatisDao;
import com.szf.base.dao.ibatis.IBatisPage;
import com.szf.base.web.PropertyFilter;
import com.szf.util.StringUtil;

@SuppressWarnings("unchecked")
@Transactional
public class BaseService {
	@Autowired
	protected IBatisDao ibatisDao;
	@Autowired
	protected HibernateDao hibernateDao;

	@Transactional(propagation = Propagation.SUPPORTS)
	public Page queryByIbatis(HttpServletRequest request, String ibatisSql) {
		return query(request, ibatisSql, null, new HashMap());
	}

	@Transactional(propagation = Propagation.SUPPORTS)
	public Page queryByIbatis(HttpServletRequest request, String ibatisSql, Map param) {
		return query(request, ibatisSql, null, param);
	}

	/**封装hibernate的查询条件,前台须满足一定的命名规范,详见PropertyFilter.java
	 * @param request
	 * @param clazz
	 * @return
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public Page queryByHibernate(HttpServletRequest request, Class clazz) {
		return query(request, null, clazz, null);
	}

	@Transactional(propagation = Propagation.SUPPORTS)
	private Page query(HttpServletRequest request, String ibatisSql, Class clazz, Map param) {
		java.util.List<PropertyFilter> list = new ArrayList<PropertyFilter>();
		Map map = request.getParameterMap();
		java.util.Iterator it = map.keySet().iterator();
		String orderBy = "";
		while (it.hasNext()) {
			String key = (String) it.next();
			String val = request.getParameter(key);
			if (key.equals("orderby")) {
				orderBy = val;
			}
			if (key.indexOf("q_") == -1 || StringUtils.isEmpty(val)) {
				continue;
			}
			PropertyFilter filter = new PropertyFilter(key, val);
			list.add(filter);
		}
		Page page = null;
		if (clazz != null) {
			HibernatePage hibernatePage = new HibernatePage(request);
			hibernatePage.setQueryClass(clazz);
			for (PropertyFilter filter : list) {
				hibernatePage.setCondition(filter.getPropertyName(), filter.getMatchType()
						.getValue(), filter.getPropertyValue());
			}
			if (orderBy.length() > 0) {
				hibernatePage.setOrderBy(orderBy);
			}
			query(hibernatePage);
			page = hibernatePage;
		}
		else if (StringUtils.isNotEmpty(ibatisSql)) {
			IBatisPage ibatisPage = new IBatisPage(request);
			if (param == null) {
				param = new HashMap();
			}
			for (PropertyFilter filter : list) {
				resetIbatisValue(filter);
				param.put(filter.getPropertyName(), filter.getPropertyValue());

			}
			ibatisPage.setParameter(ibatisSql, param);
			query(ibatisPage);
			page = ibatisPage;

		}
		return page;

	}

	private void resetIbatisValue(PropertyFilter filter) {
		Object oriVal = filter.getPropertyValue();
		String matchType = filter.getMatchType().getValue();
		if (matchType.equals("%value%")) {
			filter.setPropertyValue("%" + oriVal + "%");
		}
		else if (matchType.equals("%value")) {
			filter.setPropertyValue("%" + oriVal);
		}
		else if (matchType.equals("value%")) {
			filter.setPropertyValue(oriVal + "%");
		}
		else if (matchType.equals("IN")) {
			filter.setPropertyValue(StringUtil.getInString(oriVal));
		}

	}

	@Transactional(propagation = Propagation.SUPPORTS)
	public HibernatePage query(final HibernatePage hibernatePage) {
		return this.query(hibernatePage, false);
	}

	/**根据HibernatePage(Hibernate查询条件及分页管理包装类)查询符合条件的对象，把查询结果list及count放置到该Page并返回
	 * @param hibernatePage Hibernate查询条件及分页管理包装类
	 * @return HibernatePage 包含查询结果list及count
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public HibernatePage query(final HibernatePage hibernatePage, final boolean isCache) {
		return hibernateDao.query(hibernatePage, false);
	}

	/**
	 * 根据IBatisPage(IBatis查询条件及分页管理包装类)查询符合条件的对象，把查询结果list及count放置到该Page并返回
	 *
	 * @param ibatisPage IBatis查询条件及分页管理包装类
	 * @return IBatisPage 包含查询结果list及count
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public IBatisPage query(IBatisPage ibatisPage) {
		return ibatisDao.query(ibatisPage);
	}
}
